# This is a BitKeeper generated diff -Nru style patch. # # ChangeSet # 2004/07/02 15:41:59-06:00 bjorn.helgaas@hp.com # ia64: round iommu allocations to power-of-two sizes. # # Round IOVA allocations to power-of-two sizes to avoid # REO/Grande defect AR2305. # # arch/ia64/hp/common/sba_iommu.c # 2004/07/02 15:41:56-06:00 bjorn.helgaas@hp.com +9 -0 # Round IOVA allocations to power-of-two sizes to avoid # REO/Grande defect AR2305. # diff -Nru a/arch/ia64/hp/common/sba_iommu.c b/arch/ia64/hp/common/sba_iommu.c --- a/arch/ia64/hp/common/sba_iommu.c 2004-07-14 15:22:24 -07:00 +++ b/arch/ia64/hp/common/sba_iommu.c 2004-07-14 15:22:24 -07:00 @@ -447,6 +447,14 @@ ASSERT(((unsigned long) ioc->res_hint & (sizeof(unsigned long) - 1UL)) == 0); ASSERT(res_ptr < res_end); + + /* + * N.B. REO/Grande defect AR2305 can cause TLB fetch timeouts + * if a TLB entry is purged while in use. sba_mark_invalid() + * purges IOTLB entries in power-of-two sizes, so we also + * allocate IOVA space in power-of-two sizes. + */ + bits_wanted = 1UL << get_iovp_order(bits_wanted << PAGE_SHIFT); if (bits_wanted > (BITS_PER_LONG/2)) { /* Search word at a time - no mask needed */ for(; res_ptr < res_end; ++res_ptr) { @@ -583,6 +591,7 @@ unsigned long *res_ptr = (unsigned long *) &((ioc)->res_map[ridx & ~RESMAP_IDX_MASK]); int bits_not_wanted = size >> iovp_shift; + bits_not_wanted = 1UL << get_iovp_order(bits_not_wanted << PAGE_SHIFT); /* 3-bits "bit" address plus 2 (or 3) bits for "byte" == bit in word */ unsigned long m = RESMAP_MASK(bits_not_wanted) << (pide & (BITS_PER_LONG - 1));